package com.hilinos.gb.gb28181.application.impl;

import java.util.Collections;
import java.util.Date;
import java.util.List;

import com.google.common.eventbus.Subscribe;
import com.hilinos.gb.gb28181.cmd.ICommand;
import com.hilinos.gb.gb28181.processor.event.DeviceKeepLiveEvent;
import com.hilinos.gb.gb28181.processor.event.DeviceOfflineEvent;
import com.hilinos.gb.gb28181.processor.event.DeviceRegisterEvent;
import com.hilinos.gb.gb28181.repository.IDeviceRepository;
import com.hilinos.gb.gb28181.repository.mysql.mapper.po.Device;
import com.hilinos.hilincommon.event.IEventBus;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

@Component
public class SipApp implements IEventBus {

    @Autowired
    private ICommand iCommand;

    @Autowired
    private IDeviceRepository iDeviceRepository;

    /**
     * 注册成功
     *
     * @param registerEvent
     */
    @Subscribe
    public void registerSuccess(DeviceRegisterEvent registerEvent) {
        iCommand.deviceInfoQuery(registerEvent.getDevice());
        iCommand.catalogQuery(registerEvent.getDevice());
    }

    /**
     * 设备离线
     *
     * @param offlineEvent
     */
    @Subscribe
    public void offline(DeviceOfflineEvent offlineEvent) {
        iDeviceRepository.outlines(Collections.singletonList(offlineEvent.getDeviceId()));
    }

    /**
     * 收到心跳处理
     *
     * @param keepLiveEvent
     */
    @Subscribe
    public void keepAlive(DeviceKeepLiveEvent keepLiveEvent) {
        // 把设备设置为上线，设置心跳时间
        Device device = Device.builder()
                .deviceId(keepLiveEvent.getDeviceId())
                .online(Device.STATUS_ONLINE)
                .heartbeatTime(new Date())
                .build();
        iDeviceRepository.update(device);
    }

    /**
     * 每五分钟主动查询一次所有在线设备的子设备
     */
    @Scheduled(fixedRate = 300 * 1000)
    public void refreshDevice() {
        List<Device> deviceList = iDeviceRepository.queryOnlineDevice();
        for (Device device : deviceList) {
            if (!ObjectUtils.isEmpty(device.getIp())) {
                iCommand.catalogQuery(device);
            }
        }
    }

    /**
     * 处理设备，更新长时间没心跳的设备（当作掉线处理）
     */
    @Scheduled(fixedRate = 300 * 1000)
    public void dealErrorOnlineDevice() {
        List<String> offlineDeviceIds = iCommand.dealErrorOnlineDevice(iDeviceRepository.queryOnlineDevice());
        iDeviceRepository.outlines(offlineDeviceIds);
    }

}